package com.dingding.order.core.publish.biz.impl;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.http.HttpStatus;
import org.apache.log4j.Logger;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.dingding.common.core.base.daox.ICriteriaBaseDao;
import com.dingding.common.core.base.daox.ISQLBaseDao;
import com.dingding.common.core.base.dto.AbstractResponse;
import com.dingding.common.core.base.dto.ResponseEntity;
import com.dingding.common.core.beans.special.Specialuserinfo;
import com.dingding.common.core.beans.special.UserspecialorderT;
import com.dingding.common.core.util.DateFormatUtil;
import com.dingding.common.core.util.ToolUtil;
import com.dingding.common.core.util.paravalidate.ValiResult;
import com.dingding.common.core.util.paravalidate.ValidateUtil;
import com.dingding.facade.queue.facade.IQueueFacade;
import com.dingding.facade.special.ISpecialOrderFacade;
import com.dingding.order.code.PublishOrderCodeMsg;
import com.dingding.order.core.publish.biz.IPublishSpecialOrderService;
import com.dingding.order.core.publish.dao.IPublishSpecialOrderDao;
import com.dingding.order.dto.publish.special.AssignOrderDTO;
import com.dingding.order.dto.publish.special.ReqPublishOrderDTO;
import com.dingding.order.dto.publish.special.ResPublishOrderDTO;

/**
 * 
 * @ClassName: PublishOrderServiceImpl 
 * @Description: 发布订单Service实现类
 * @author YHQ
 * @date 2016年8月18日 下午2:17:57
 * @since V2.4.0
 * 
 */
@Component("publishSpecialOrderService")
public class PublishSpecialOrderServiceImpl extends AbstractResponse<ResPublishOrderDTO,ReqPublishOrderDTO> implements IPublishSpecialOrderService {

	private Logger log = Logger.getLogger(this.getClass());
	
	@Resource(name="publishSpecialOrderDao")
	private IPublishSpecialOrderDao publishSpecialOrderDao;
	
	@Resource(name="criteriaBaseDao")
	private ICriteriaBaseDao criteriaBaseDao;
	
	@Resource(name = "specialOrderFacade")
	private ISpecialOrderFacade specialOrderFacade;
	
	@Resource(name = "queueFacade")
	private IQueueFacade queueFacade;
	
	@Resource(name = "SQLBaseDao")
	private ISQLBaseDao sqlBaseDao;
	
	/**
	 * 
	 * @Title: publishOrder 
	 * @Description: 发布订单 
	 * @param reqPublishOrderDTO 待发布的订单信息
	 * @author YHQ 
	 * @since V2.4.0
	 * @return ResponseEntity<ResPublishOrderDTO>    返回类型
	 * 
	 */
	@Override
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public String publishOrder(String requestData) {
		
		// 发布订单响应信息
		ResponseEntity<ResPublishOrderDTO> response = new ResponseEntity<ResPublishOrderDTO>();
		
		// 客户端请求参数
		ReqPublishOrderDTO reqPublishOrderDTO = super.parseRequestJson(requestData);
		
		// 判断是否发布订单条件
		boolean flag = billingConditions(response, reqPublishOrderDTO);
		
		if(!flag){
			return super.responseBeanToJson(response);
		}
		
		// 发单操作
		UserspecialorderT userspecialordert = publishSpecialOrderDao.releaseOrder(reqPublishOrderDTO);
		
		// 发布订单操作成功，将订单信息加入队列
		if(userspecialordert != null){
			
			this.publishSpecialOrderDao.addSpecialOrderToQueue(response, userspecialordert);
		}
		
		return super.responseBeanToJson(response);
	}

	/**
	 * 
	 * @Title: billingConditions
	 * @Description: 发单条件
	 * @param response 发布订单响应Bean
	 * @param reqPublishOrderDTO 待发布的订单信息
	 * @author YHQ
	 * @return boolean true:符合发单条件 false:不符合发布订单条件
	 * 
	 */
	public boolean billingConditions(ResponseEntity<ResPublishOrderDTO> response,ReqPublishOrderDTO reqPublishOrderDTO){
		
		// 判断客户端请求数据是否为空
		ValiResult valiResult = ValidateUtil.validateBeanIsAvaliable(reqPublishOrderDTO, ReqPublishOrderDTO.class);

		if (!valiResult.isAvailable()) {
			response.setCode(HttpStatus.SC_FORBIDDEN);
			response.setErrorMessage(PublishOrderCodeMsg.DATA_NULL_PARAM_MESSAGE);// 客户端请求数据为空
			response.setPromptMessage(PublishOrderCodeMsg.APP_ERROR);// 客户端请求数据为空
			response.setNullProperties(valiResult.getNullFieldName());
			log.error("为空字段为：" + valiResult.getNullFieldName());
			return false;
		}
		
		if(reqPublishOrderDTO.getSetOutType() == 2 && ToolUtil.isBlank(reqPublishOrderDTO.getSetOutTime())){
			
			response.setCode(HttpStatus.SC_FORBIDDEN);
			response.setErrorMessage(PublishOrderCodeMsg.DATA_NULL_PARAM_MESSAGE);// 客户端请求数据为空
			response.setPromptMessage(PublishOrderCodeMsg.APP_ERROR);// 客户端请求数据为空
			response.setNullProperties("setOutTime");
			return false;
		}
		
		// 发布专车预约订单，订单的出发时间必须在当前时间的十五分钟之后
		if(reqPublishOrderDTO.getSetOutType() == 2 && ToolUtil.isNotBlank(reqPublishOrderDTO.getSetOutTime())){
			
			// 当前时间
			Long currentTime = new Date().getTime();
			// 预约订单出发时间
			Long setOutTime = DateFormatUtil.yyyy_MM_dd_HHmmss(reqPublishOrderDTO.getSetOutTime()).getTime();
			
			if(((setOutTime - currentTime)/1000/60) < 15){
				response.setCode(HttpStatus.SC_FORBIDDEN);
				response.setErrorMessage("预约订单须提前十五分钟下单");
				response.setPromptMessage("预约订单须提前十五分钟下单");
				return false;
			}
		}
		
		// 判断该用户是否存在未完成订单
		List<UserspecialorderT> userspecialorderts = publishSpecialOrderDao.getUserSpecialOrdertList(reqPublishOrderDTO.getPlaceOrderUserId());
		
		if(userspecialorderts != null && userspecialorderts.size() > 0){
			
			for (UserspecialorderT userspecialorderT : userspecialorderts) {
				
				if(userspecialorderT.getSetOutType() == reqPublishOrderDTO.getSetOutType()){
					
					response.setCode(HttpStatus.SC_FORBIDDEN);
					response.setErrorMessage(PublishOrderCodeMsg.NOT_COMPLETED_ORDER_MESSAGE);// 您尚有未完成订单，请先完成！
					response.setPromptMessage(PublishOrderCodeMsg.NOT_COMPLETED_ORDER_MESSAGE);
					log.error("有未完成订单，用户为：" + reqPublishOrderDTO.getPlaceOrderUserId());
					return false;
				}
				
			}
			
		}
		
		return true;
	}
	
	
	
	
	
	
	/**
	 * 
	 * @Title: assignOrder 
	 * @Description: 指派订单操作
	 * @param oid 订单Id
	 * @author YHQ 
	 * @return void    返回类型
	 * 
	 */
	public void assignOrder(UserspecialorderT userspecialordert){
		
		this.queueFacade.addSpecialOrderToQueue(userspecialordert);
	}
	
	/**
	 * 
	 * @Title: getSpecialuserinfo 
	 * @Description: 根据用户Id获取专车用户信息
	 * @param userId 用户Id
	 * @author YHQ 
	 * @return Specialuserinfo    返回类型
	 * 
	 */
	public Specialuserinfo getSpecialuserinfo(String userId){
		
		Criterion criterion = Restrictions.eq("userId", userId);
		
		try {
			return criteriaBaseDao.queryCriteriaListUnique(Specialuserinfo.class, criterion);
		} catch (Exception e) {
			log.error("根据用户Id获取专车用户信息时出现异常   类："+this.getClass()+" getSpecialuserinfo()", e);
		}
		
		return null;
	}
	
	/**
	 * 
	 * @Title: geAssignOrderDTO 
	 * @Description:  获取专车
	 * @param specialuserinfo 下单人信息
	 * @param userspecialordert 专车订单
	 * @author YHQ 
	 * @since V2.4.0
	 * @return AssignOrderDTO    返回类型
	 * 
	 */
	public AssignOrderDTO geAssignOrderDTO(Specialuserinfo specialuserinfo,UserspecialorderT userspecialordert){
		
		AssignOrderDTO assignOrderDTO = new AssignOrderDTO();
		
		assignOrderDTO.setDistance(userspecialordert.getDistance());// 订单里程
		assignOrderDTO.setEndAddress(userspecialordert.getEndAddress());// 目的地
		assignOrderDTO.setEndLatitude(userspecialordert.getEndLatitude());// 目的地纬度
		assignOrderDTO.setEndLongitude(userspecialordert.getEndLongitude());// 目的地经度
		assignOrderDTO.setNickName(specialuserinfo.getNickName());// 昵称
		assignOrderDTO.setOid(userspecialordert.getSpecialOrderId());// 订单Id
		assignOrderDTO.setOrderStatus(userspecialordert.getOrderStatus());// 订单状态   1:待指派 2:待上车(已指派) 3:已上车 4:待支付(已到达) 5:已完成 6:已取消
		assignOrderDTO.setSetOutTime(userspecialordert.getSetOutTime());// 出发时间
		assignOrderDTO.setSex(specialuserinfo.getSex());// 性别   1：男  2：女
		assignOrderDTO.setStartAddress(userspecialordert.getStartAddress());// 出发地
		assignOrderDTO.setStartLatitude(userspecialordert.getStartLatitude());// 起点纬度
		assignOrderDTO.setStartLongitude(userspecialordert.getStartLongitude());// 起点经度
		assignOrderDTO.setTelePhone(specialuserinfo.getTelPhone());// 手机号
		assignOrderDTO.setUserAvatar(specialuserinfo.getUserAvatar());// 用户头像
		assignOrderDTO.setUserId(userspecialordert.getPlaceOrderUserId());// 用户Id(下单人)
		assignOrderDTO.setUserTabloidAvatar(specialuserinfo.getUserTabloidAvatar());// 用户缩略图
		
		return assignOrderDTO;
	}
	

}
